﻿using System;
using System.Drawing;

namespace V.Utility
{
    /// <summary>
    /// 验证码
    /// </summary>
  public  class ValidCode
  {
    public byte[] GenerateVerifyImage(int nLen, ref string strKey)
    {
      int nBmpWidth = 13 * nLen + 5;
      int nBmpHeight = 25;
      System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(nBmpWidth, nBmpHeight);

      // 1. 生成随机背景颜色
      int nRed, nGreen, nBlue;  // 背景的三元色
      System.Random rd = new Random((int)System.DateTime.Now.Ticks);
      nRed = rd.Next(255) % 128 + 128;
      nGreen = rd.Next(255) % 128 + 128;
      nBlue = rd.Next(255) % 128 + 128;

      //nRed = 255;
      //nGreen = 246;
      //nBlue = 215;


      // 2. 填充位图背景
      System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
      graph.FillRectangle(new SolidBrush(System.Drawing.Color.FromArgb(nRed, nGreen, nBlue)), 0, 0, nBmpWidth, nBmpHeight);

      // 3. 绘制干扰线条，采用比背景略深一些的颜色
      int nLines = 3;
      System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Color.FromArgb(nRed - 20, nGreen - 20, nBlue - 15), 2);
      for (int a = 0; a < nLines; a++)
      {
        int x1 = rd.Next() % nBmpWidth;
        int y1 = rd.Next() % nBmpHeight;
        int x2 = rd.Next() % nBmpWidth;
        int y2 = rd.Next() % nBmpHeight;
        graph.DrawLine(pen, x1, y1, x2, y2);
      }

      //画图片的前景噪音点
      for (int i = 0; i < 120; i++)
      {
        int x = rd.Next(nBmpWidth);
        int y = rd.Next(nBmpHeight);
        bmp.SetPixel(x, y, Color.FromArgb(nRed - 30, nGreen - 30, nBlue - 20));
      }
      //画边框
      //graph.DrawRectangle(new Pen(Color.Silver), 0, 0, nBmpWidth - 1, nBmpHeight - 1);

      // 采用的字符集，可以随即拓展，并可以控制字符出现的几率(0跟O分不清，所以都给清了)
      string strCode = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";

      // 4. 循环取得字符，并绘制
      string strResult = "";
      for (int i = 0; i < nLen; i++)
      {
        int x = (i * 13 + rd.Next(3));
        int y = rd.Next(4) + 1;
        // 确定字体
        System.Drawing.Font font = new System.Drawing.Font("Courier New",
         12 + rd.Next() % 4,
         System.Drawing.FontStyle.Bold);
        char c = strCode[rd.Next(strCode.Length)];  // 随机获取字符
        strResult += c.ToString();

        // 绘制字符
        graph.DrawString(c.ToString(),
         font,
         new SolidBrush(System.Drawing.Color.FromArgb(nRed - 80 + y * 3, nGreen - 80 + y * 3, nBlue - 60 + y * 3)),
         x,
         y);
      }

      // 5. 输出字节流
      System.IO.MemoryStream bstream = new System.IO.MemoryStream();
      bmp.Save(bstream, System.Drawing.Imaging.ImageFormat.Jpeg);
      bmp.Dispose();
      graph.Dispose();

      strKey = strResult;
      byte[] byteReturn = bstream.ToArray();
      bstream.Close();

      return byteReturn;
    }
      /// <summary>
      /// 产生KeyCode码
      /// </summary>
      /// <param name="nlen">产生位数</param>
      /// <returns>KeyCode码</returns>
    public static string GenerateKeys(int nlen)
    {
        string strResult = string.Empty;
        //string strCode = "123456789ABCDEFGHIJKLMNPQRSTUVWXYZ";
        string strCode = "1234567890";
        System.Random rd = new Random((int)System.DateTime.Now.Ticks);
        for (int i = 0; i < nlen; i++)
        {
            char c = strCode[rd.Next(strCode.Length)];  // 随机获取字符
            strResult += c.ToString();
        }
        return strResult;
    }
  }
}